package com.zitangkou.user.util;

import com.zitangkou.common.enums.CipherAlgorithmEnum;
import com.zitangkou.common.enums.SecretEnum;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;

/**
 * 加密解密工具类
 *
 * @author Deng Ningning
 * @date 2020/9/3 14:32
 */
@Slf4j
public class CryptUtil {

    private CryptUtil() {
    }

    /**
     * 加密解密
     *
     * @param data
     * @param cipherAlgorithmEnum
     * @param cipherMode
     * @return byte[]
     * @author Deng Ningning
     * @date 2020/9/3 14:46
     */
    public static byte[] encryptOrDecrypt(byte[] data, SecretEnum secretEnum, CipherAlgorithmEnum cipherAlgorithmEnum, int cipherMode)
            throws Exception {
        // 还原密钥
        Key key = base64KeyStrToKey(secretEnum, cipherAlgorithmEnum);
        Cipher cipher;
        byte[] cryptData;
        // 实例化
        cipher = Cipher.getInstance(cipherAlgorithmEnum.getCipher());
        // 初始化，设置加密/解密模式
        cipher.init(cipherMode, key);
        cryptData = cipher.doFinal(data);
        return cryptData;
    }

    /**
     * base64字符串形式的密钥转换成密钥对象
     *
     * @param cipherAlgorithmEnum
     * @return java.security.Key
     * @author Deng Ningning
     * @date 2020/9/3 14:44
     */
    public static Key base64KeyStrToKey(SecretEnum secretEnum, CipherAlgorithmEnum cipherAlgorithmEnum)
            throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException {
        KeySpec keySpec;
        SecretKeyFactory secretKeyFactory;
        // 实例化密钥材料
        switch (cipherAlgorithmEnum) {
            case DES_CIPHER_ALGORITHM:
                keySpec = new DESKeySpec(Base64.getDecoder().decode(secretEnum.getValue()));
                break;
            default:
                throw new RuntimeException();
        }
        // 实例化密钥工厂
        secretKeyFactory = SecretKeyFactory.getInstance(cipherAlgorithmEnum.getAlgorithm());
        // 生成密钥对象
        return secretKeyFactory.generateSecret(keySpec);
    }

    /**
     * 初始化密钥返回密钥base64字符串形式
     *
     * @param cipherAlgorithmEnum
     * @return java.lang.String
     * @author Deng Ningning
     * @date 2020/9/3 14:45
     */
    public static String initKey(CipherAlgorithmEnum cipherAlgorithmEnum) throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(cipherAlgorithmEnum.getAlgorithm());
        // 默认密钥长度
        keyGenerator.init(new SecureRandom());
        // 生成密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 转 base64 保存
        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
    }

    /**
     * 消息摘要算法
     *
     * @param data
     * @param cipherAlgorithmEnum
     * @return byte[]
     * @author Deng Ningning
     * @date 2020/9/3 14:47
     */
    public static byte[] encodeMessageDigest(byte[] data, CipherAlgorithmEnum cipherAlgorithmEnum) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance(cipherAlgorithmEnum.getAlgorithm());
        } catch (NoSuchAlgorithmException e) {
            log.info(e.getMessage());
            return new byte[]{};
        }
        return messageDigest.digest(data);
    }
}
